#include "com_dc_android_can_CAN.h"
#include "mcp2515.h"

///#include "spi_can_test.h"
#include <signal.h>
#include <android/log.h>
///#include <unitrans/datadefine.h>

#define LOG_TAG  "C_TAG"
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#define LOGE(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);
MCP2515 mcp;
int result;

void SigioDispose(int signal){
    //CanDataType canDataType = mcp.CanDataReadOnce();
    //LOGD("Can ID = %d ",canDataType.id);
    //int canId = canDataType.id;
}


JNIEXPORT jint JNICALL Java_com_dc_android_1can_CAN_init
        (JNIEnv *, jclass)
{

    uint8_t dataBuf[] = {0xaa, 0xbb, 0xcc, 0xdd};
    signal(SIGIO, SigioDispose);
    result = mcp.Init();
    if( result >= 0){


//        LOGD("CAN devices ok  %d \r\n", result);
    } else {
//        LOGD("CAN devices %d \r\n", result);
    }


    /**int device = CAN_init();
    if( device >= 0){

        while(1){
        LOGD("CAN devices ok : %d \r\n", device);
                CAN_Write(0xaa, dataBuf, 4);
        }

    } else {
        LOGD("CAN devices ");
     } */
    return result;
}


/*
 * Class:     com_dc_can_test_can_CAN
 * Method:    Write
 * Signature: (I[BI)I
 */
JNIEXPORT jint JNICALL Java_com_dc_android_1can_CAN_Write
        (JNIEnv *env, jclass, jint address, jbyteArray dataBuf, jint len)
{
    jbyte *jby = env->GetByteArrayElements(dataBuf, 0);
    struct CanDataType temp;

    LOGD("**********************************************");
    for (int i = 0; i <  env->GetArrayLength(dataBuf) ; ++i) {
        LOGD("java_data = %2x" ,  jby[i]);
    }

    memcpy(temp.dataBuf, jby + 4, len);
    temp.length = len;
    temp.id = jby[1];

    uint8_t byte_data[2];
    byte_data[0] = (uint8_t)jby[2] & 0xff;
    byte_data[1] = (uint8_t)jby[3] & 0xff;

    temp.cmdWord = (*((uint16_t*)byte_data)) & 0xfff;

    if((*((uint16_t*)byte_data)) & 0xf000) {
        temp.dir = false;
    } else {
        temp.dir = true;
    }

    LOGD("____len = %2x" ,  temp.length);
    LOGD("____id = %2x" ,  temp.id);
    LOGD("____cmdWord = %2x" ,  temp.cmdWord);
    LOGD("____dir = %2x" ,  temp.dir);
    for (int i = 0; i < 4 ; ++i) {
        LOGD("____data = %2x" ,  temp.dataBuf[i]);
    }

    int mcpRes = mcp.SendCanData(temp);
    return mcpRes;
}


/*
 * Class:     com_dc_can_test_can_CAN
 * Method:    Read
 * Signature: (I[BI)I
 */
JNIEXPORT jint JNICALL Java_com_dc_android_1can_CAN_Read
        (JNIEnv *, jclass, jint, jbyteArray, jint)
{

}

/*
 * Class:     com_dc_android_can_CAN
 * Method:    ReadData
 * Signature: ()[B
 */
JNIEXPORT jbyteArray JNICALL Java_com_dc_android_1can_CAN_ReadData
        (JNIEnv *, jclass){

}

extern "C"
JNIEXPORT jobject JNICALL
Java_com_dc_android_1can_CAN_ReadConDataType(JNIEnv *env, jclass type) {
    // TODO
    CanDataType canDataType;
    if(mcp.CanDataReadOnce(canDataType)) {

        int l = canDataType.length;
        int i = canDataType.id;
        int cmd = canDataType.cmdWord;
        if(i != 0x59) {
            // 1                                 com.dc.android_can.can.CanDataType
            jclass objectClass = env->FindClass("com/dc/android_can/can/CanDataType");
            // 2
            jmethodID mid = env->GetMethodID(objectClass, "<init>", "()V");
            jobject obj = env->NewObject(objectClass, mid);
            // 3  第二个字段为上层结构体的属性
            jfieldID id = (env)->GetFieldID(objectClass, "id", "I");
            jfieldID len = (env)->GetFieldID(objectClass, "len", "I");
            jfieldID cmdWord = (env)->GetFieldID(objectClass, "cmdWord", "I");
            jfieldID dataBuf = (env)->GetFieldID(objectClass, "buf", "[B");
            // 5
            //给每一个实例的变量赋值
            (env)->SetIntField(obj, id, i);
            (env)->SetIntField(obj, len, l);
            (env)->SetIntField(obj, cmdWord, cmd);
            //数组赋值
            jbyteArray jarr = env->NewByteArray(4);
            jbyte *jby = env->GetByteArrayElements(jarr, 0);
            memcpy(jby, canDataType.dataBuf, 4);
            env->SetByteArrayRegion(jarr, 0, 4, jby);

            env->SetObjectField(obj, dataBuf, jarr);
            return obj;
        }
    }
    return NULL;
}

